#include "stdafx.h"
#include "PlayerPet.h"
PlayerPet::PlayerPet(PlayerId stPlayerId)
	:PlayerSkill(stPlayerId)
{
	LOGGER_INFO("PlayerPet:%p,",this);
}
PlayerPet::~PlayerPet()
{
	LOGGER_INFO("~PlayerPet:%p,",this);
	for (UInt32 i = 0; i < m_arPets.size(); i++)
	{
		singleton<PetManager>::instance().Remove(m_arPets[i]);
	}
}

void PlayerPet::OnTimerSendPets(UInt32 nTimerId)
{
	if(m_nTimerSendPets != nTimerId)
	{
		LOGGER_ERROR("OnTimerSendPets,m_nTimerSendPets:%d,nTimerId:%d",m_nTimerSendPets,nTimerId);
		DestroyTimer(nTimerId);
	}	
	DestroyTimer(m_nTimerSendPets);
	sendPets();
}

void PlayerPet::addPet(Int32 csv_id)
{
	if (m_arPets.size() >= MAX_PETS_SIZE)
	{
		LOGGER_ERROR("addPet,m_arPets.size() >= CharInfo::MAX_PETS_SIZE");
		return;
	}
	Int32 nInnerId = generatePetInnerId();
	if (nInnerId == 0)
		return;
	Pet *pPet = singleton<PetManager>::instance().CreateFromCSVId(csv_id);
	if (pPet == NULL)
	{
		LOGGER_ERROR("addPet,pPet == NULL,csv_id:%d",csv_id);
		return;
	}
	pPet->SetOwnerPlayer((Player*)this);
	pPet->updateMaxValue();

	if (!pPet->hasSkill(SKILL_ID_JD))pPet->addSkill(SKILL_ID_JD);
	if (!pPet->hasSkill(SKILL_ID_FY))pPet->addSkill(SKILL_ID_FY);

	PetCSVInfo* pInfo = pPet->GetPetCSVInfo();
	if (pInfo == NULL) return;
	Int32 nSkillId = pInfo->skill_0;
	if (nSkillId != 0 && rand() % 10000 < pInfo->has_skill_odds_0)
	{
		if (!pPet->hasSkill(nSkillId))pPet->addSkill(nSkillId);
	}
	nSkillId = pInfo->skill_1;
	if (nSkillId != 0 && rand() % 10000 < pInfo->has_skill_odds_1)
	{
		if (!pPet->hasSkill(nSkillId))pPet->addSkill(nSkillId);
	}
	nSkillId = pInfo->skill_2;
	if (nSkillId != 0 && rand() % 10000 < pInfo->has_skill_odds_2)
	{
		if (!pPet->hasSkill(nSkillId))pPet->addSkill(nSkillId);
	}
	nSkillId = pInfo->skill_3;
	if (nSkillId != 0 && rand() % 10000 < pInfo->has_skill_odds_3)
	{
		if (!pPet->hasSkill(nSkillId))pPet->addSkill(nSkillId);
	}
	PetInfo& info = pPet->GetPetInfo();
	info.m_szCharName[MAX_CHAR_NAME_SIZE-1] = '\0';
	if (pInfo->name.size() < MAX_CHAR_NAME_SIZE && !pInfo->name.empty())
	{
		strcpy(info.m_szCharName,pInfo->name.c_str());
	}
	info.m_nImageId = pInfo->image_id;
	info.m_nInnerId = nInnerId;
	m_arPets.push_back(pPet->GetPetId());
	PrepareSendPets();
	PrepareSyncCharInfo();
	luaCallTaskFunction1("onTaskAddPet",csv_id);
}
bool PlayerPet::hasPet(Int32 csv_id)
{
	for (UInt32 i = 0; i < m_arPets.size(); i++)
	{
		Pet *pPet = singleton<PetManager>::instance().Get(m_arPets[i]);
		if (pPet != NULL)
		{
			if(pPet->GetPetInfo().csv_id == csv_id)
				return true;
		}
	}
	return false;
}

Pet* PlayerPet::getPetByIndex(Int32 nIndex)
{
	if (nIndex < 0 || nIndex >= (Int32)m_arPets.size())
	{
		LOGGER_ERROR("getPetByIndex,nIndex < 0 || nIndex >= m_arPets.size()");
		return NULL;
	}
	return singleton<PetManager>::instance().Get(m_arPets[nIndex]);
}
Pet* PlayerPet::getPetByInnerId(Int32 nInnerId)
{	
	for (UInt32 i = 0; i < m_arPets.size(); i++)
	{
		Pet *pPet = singleton<PetManager>::instance().Get(m_arPets[i]);
		if (pPet != NULL)
		{
			if (pPet->GetPetInfo().m_nInnerId == nInnerId)
				return pPet;
		}
	}
	return NULL;
}
PetInfo* PlayerPet::getPetInfoByInnerId(CharInfo& stCharInfo,Int32 nInnerId)
{
	if(stCharInfo.m_nPetsSize > MAX_PETS_SIZE)
		return NULL;
	for (UInt32 i = 0; i < stCharInfo.m_nPetsSize; i++)
	{
		if(stCharInfo.m_arPets[i].m_nInnerId == nInnerId)
			return &(stCharInfo.m_arPets[i]);
	}
	return NULL;
}
Int32 PlayerPet::getIndexByPetId(PetId id)
{
	Int32 nIndex = -1;
	std::vector<PetId>::iterator iter = m_arPets.begin();
	std::vector<PetId>::iterator iterend = m_arPets.end();
	for (; iter != iterend; iter++)
	{
		if ((*iter) == id)
		{
			return nIndex;
		}
		nIndex++;
	}
	return nIndex;
}
void PlayerPet::removePetByPetId(PetId id)
{
	std::vector<PetId>::iterator iter = m_arPets.begin();
	std::vector<PetId>::iterator iterend = m_arPets.end();
	for (; iter != iterend; iter++)
	{
		if ((*iter) == id)
		{
			singleton<PetManager>::instance().Remove(id);
			m_arPets.erase(iter);
			return;
		}
	}
	PrepareSyncCharInfo();
}
void PlayerPet::decodePets()
{
	if (m_stCharInfo.m_nPetsSize > MAX_PETS_SIZE)
	{
		LOGGER_ERROR("decodePets,m_stCharInfo.m_nPetsSize > CharInfo::MAX_PETS_SIZE");
		return;
	}
	m_arPets.clear();
	Pet *pPet = NULL;
	for (UInt32 i = 0; i < m_stCharInfo.m_nPetsSize; i++)
	{
		if (m_stCharInfo.m_arPets[i].csv_id != 0 )
		{
			m_stCharInfo.m_arPets[i].m_szCharName[MAX_CHAR_NAME_SIZE-1] = '\0';
			pPet = singleton<PetManager>::instance().CreateFromPetInfo(m_stCharInfo.m_arPets[i]);
			if (pPet == NULL)
			{
				LOGGER_ERROR("decodePets,m_stCharInfo.m_arPets[i].csv_id != 0,but pPet == NULL,csv_id:%d",m_stCharInfo.m_arPets[i].csv_id);
			}
			else
			{
				pPet->SetOwnerPlayer((Player*)this);
				pPet->updateMaxValue();
				pPet->decodeSkills();
				m_arPets.push_back(pPet->GetPetId());
			}
		}
	}
	if(m_stCharInfo.m_nPetJoinBattleIndex < 0 || m_stCharInfo.m_nPetJoinBattleIndex >= (Int32)m_arPets.size())
		m_stCharInfo.m_nPetJoinBattleIndex = -1;
}
void PlayerPet::encodePets()
{
	if (m_arPets.size() > MAX_PETS_SIZE)
	{
		LOGGER_ERROR("encodePets,m_arPets.size() > CharInfo::MAX_PETS_SIZE");
		return;
	}

	m_stCharInfo.m_nPetsSize = m_arPets.size();
	for (UInt32 i = 0; i < m_arPets.size(); i++)
	{
		Pet *pPet = singleton<PetManager>::instance().Get(m_arPets[i]);
		if (pPet != NULL)
		{
			pPet->encodeSkills();
			m_stCharInfo.m_arPets[i] = pPet->GetPetInfo();
		}
	}
}
void PlayerPet::sendPets()
{
	if(m_stCharInfo.m_nPetJoinBattleIndex < 0 || m_stCharInfo.m_nPetJoinBattleIndex >= (Int32)m_arPets.size())
		m_stCharInfo.m_nPetJoinBattleIndex = -1;
	Pet* pPet = getPetByIndex(m_stCharInfo.m_nPetJoinBattleIndex);
	if (pPet != NULL)
	{
		pPet->SetWatch(true);
	}

	PacketEncoder encoder;
	encoder.AddItem(Int32(0));
	encoder.AddItem(Int32(100));

	encoder.AddItem(Int32(m_arPets.size()));
	encoder.AddItem(Int32(m_stCharInfo.m_nPetJoinBattleIndex));
	for (UInt32 i = 0; i < m_arPets.size(); i++)
	{
		pPet = singleton<PetManager>::instance().Get(m_arPets[i]);
		if (pPet != NULL)
		{
			PetInfo& info = pPet->GetPetInfo();
			encoder.AddItem(pPet->GetPetId());
			encoder.AddItem(info.csv_id);
			encoder.AddItem(info.m_nInnerId);
			encoder.AddItem(info.m_szCharName);
			encoder.AddItem(info.m_nLevel);
			encoder.AddItem(info.m_nGrowth);
			encoder.AddItem(info.m_nEXP);
			encoder.AddItem(info.m_nEXPMax);

			encoder.AddItem(info.m_nHP + info.m_nHPAdd);
			encoder.AddItem(pPet->m_nNextPointHP + info.m_nHPAdd);
			encoder.AddItem(pPet->m_nNextPointMoneyHP);

			encoder.AddItem(info.m_nAP + info.m_nAPAdd);
			encoder.AddItem(pPet->m_nNextPointAP + info.m_nAPAdd);
			encoder.AddItem(pPet->m_nNextPointMoneyAP);

			encoder.AddItem(info.m_nDP + info.m_nDPAdd);
			encoder.AddItem(pPet->m_nNextPointDP + info.m_nDPAdd);
			encoder.AddItem(pPet->m_nNextPointMoneyDP);

			encoder.AddItem(info.m_nSP + info.m_nSPAdd);
			encoder.AddItem(pPet->m_nNextPointSP + info.m_nSPAdd);
			encoder.AddItem(pPet->m_nNextPointMoneySP);

			encoder.AddItem(info.m_nResistHL);
			encoder.AddItem(info.m_nResistBD);
			encoder.AddItem(info.m_nResistHS);

			encoder.AddItem(info.m_nPointHP);
			encoder.AddItem(info.m_nPointAP);
			encoder.AddItem(info.m_nPointDP);
			encoder.AddItem(info.m_nPointSP);
			pPet->sendSkills(encoder);

			encoder.AddItem(Int32(info.m_nBattleMode));
			for (Int32 i = 0; i < MAX_AUTO_BATTLE_SKILLS_SIZE; i++)
			{
				encoder.AddItem(Int32(info.m_arAutoBattleSkills[i]));
			}
			for (Int32 i = 0; i < MAX_AUTO_BATTLE_SKILLS_SIZE; i++)
			{
				encoder.AddItem(Int32(info.m_arAutoBattleSkillsSoul[i]));
			}
		}
	}

	SendPacket(m_stPlayerId.nSocketId,m_stPlayerId.nSocketIdOnGate,encoder);
}
Int32 PlayerPet::generatePetInnerId()
{
	if (m_arPets.size() >= MAX_PETS_SIZE)
	{
		return 0;
	}
	for (Int32 i = 1; i <= MAX_PETS_SIZE; i++)
	{
		if (getPetByInnerId(i) == NULL)
			return i;
	}
	return 0;
}

